perm filename NEARPR.IME[REV,MUS] blob
sn#290448 filedate 1977-06-23 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00003 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 EXTERNAL INTEGER ARRAY PRIMES[1:2] ∂ Bounds are ignored
C00003 00003 INTERNAL INTEGER PROCEDURE nearest_prime(
C00006 ENDMK
C⊗;
EXTERNAL INTEGER ARRAY PRIMES[1:2]; ∂ Bounds are ignored;
EXTERNAL INTEGER #PRIMES;
REQUIRE "PRIMES" LOAD_MODULE;
INTERNAL INTEGER PROCEDURE nearest_prime(
REFERENCE INTEGER n);
∂ Takes as argument an integer n in the range covered by the EXTERNAL PRIMES
table and returns as a result the index in the PRIMES table of the nearest
prime to that n. The REFERENCE argument n is set to that table entry.
;
BEGIN "nearest_prime"
INTEGER top, bot;
IF
¬((0 < n) ∧ (n ≤ PRIMES[#PRIMES]))
THEN BEGIN
PRINT(↓,"nearest_prime: 2 ≤ n ≤ ",PRIMES[#PRIMES],↓);
RETURN(PRIMES[#PRIMES]);
END;
top ← LOCATION(PRIMES[#PRIMES]);
bot ← LOCATION(PRIMES[1]);
START_CODE "binary search"
LABEL Test; ∂ Faster than linear search if #PRIMES>30;
DEFINE Key=0, i=1, hi=2, lo=3;
MOVE hi,top;
MOVE lo,bot;
MOVE Key,n;
Test:
MOVEI i,(lo); ∂ Find center of sub-table;
ADDI i,(hi);
LSH i,-1;
CAMLE Key,(i); ∂ Which half of sub-table is Key in?;
AOSA lo,i; ∂ Add 1 to compensate for truncation in LSH;
MOVEI hi,(i); ∂ New sub-table is half containing Key;
CAIGE lo,(hi); ∂ If sub-table contains only 1 element, we're done;
JRST Test;
SUB hi,bot;
AOS hi;
MOVEM hi,top;
END "binary search";
IF
(top > 1)
∧
(PRIMES[top-1]+PRIMES[top]) LSH -1 ≥ n
THEN
top ← top-1;
n ← PRIMES[top];
RETURN(top);
END "nearest_prime";